home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
UNIXLIB37B
/
!UnixLib37
/
src
/
unix
/
c
/
dirent
< prev
next >
Wrap
Text File
|
1996-11-09
|
5KB
|
291 lines
/****************************************************************************
*
* $Source: /unixb/home/unixlib/source/unixlib37/src/unix/c/RCS/dirent,v $
* $Date: 1996/10/30 21:59:01 $
* $Revision: 1.4 $
* $State: Rel $
* $Author: unixlib $
*
* $Log: dirent,v $
* Revision 1.4 1996/10/30 21:59:01 unixlib
* Massive changes made by Nick Burret and Peter Burwood.
*
* Revision 1.3 1996/09/16 21:23:52 unixlib
* CL_0002 Nick Burret
* Minor changes to file handling
* Change most error numbers, and use in assembler sources (SJC)
* Various minor bug fixes and compatability changes.
*
* Revision 1.2 1996/05/06 09:01:35 unixlib
* Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
* Saved for 3.7a release.
*
* Revision 1.1 1996/04/19 21:35:27 simon
* Initial revision
*
* Jan 1994: Alun Jones, auj@aber.ac.uk
*
* As supplied, UnixLib can only hold one directory open.
* If you try to open two, it returns a valid directory pointer,
* but overwrites the old version. For example, this stops tar from
* recursing the directory tree. dirent.c is a fixed version of
* UnixLib's dirent.
***************************************************************************/
static const char rcs_id[] = "$Id: dirent,v 1.4 1996/10/30 21:59:01 unixlib Rel $";
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/unix.h>
#include <sys/syslib.h>
#include <sys/os.h>
#include <sys/types.h>
#include <sys/swis.h>
#include <dirent.h>
#define DIRBUFSIZ 1024
#define DIRBUFSHIFT 10
#define MAXDIRS 32
static struct
{
struct dirent *__dirval;
DIR *which;
}
dirvals[MAXDIRS];
/* opendir() */
DIR *
opendir (const char *name)
{
int i;
int r[10];
_kernel_oserror *e;
register DIR *d;
char *rname;
rname = __uname ((char *)name, 0);
if (e = os_file (0x05, rname, r))
{
__seterr (e);
return (0);
}
if (r[0] != 2 && r[0] != 3) /* pjb, added support for images directories */
return (0);
if (!(d = malloc (sizeof (DIR))))
return (0);
if (!(d->dd_buf = malloc (DIRBUFSIZ)))
{
free (d);
return (0);
}
/* We have to store the original format of the name in the
dirent buffer. The user program might perform some sort of
hashing and hope that it's copy of the name is the same
as that of the dirent version. */
if (!(d->dd_name = __permstr (name)))
{
free (d->dd_buf);
free (d);
return (0);
}
d->dd_fd = 0;
d->dd_loc = 0;
d->dd_size = 0;
d->dd_bsize = DIRBUFSIZ;
d->dd_off = 0;
d->dd_off2 = 0;
for (i = 0; i < MAXDIRS; i++)
{
if (!dirvals[i].__dirval)
{
if (!(dirvals[i].__dirval = malloc (sizeof (struct dirent))))
{
free (d->dd_name);
free (d->dd_buf);
free (d);
return (0);
}
dirvals[i].which = d;
break;
}
}
return (d);
}
/* __nextdir() */
static int
__nextdir (register DIR * d)
{
int r[10];
_kernel_oserror *e;
register int i;
register char *s;
char *rname;
if (d->dd_off2 < 0)
return (-1);
/* Got to convert the filename on every usage since it could
be Unix format. */
rname = __uname (d->dd_name, 0);
r[0] = 9;
r[1] = (int) rname;
r[2] = (int) d->dd_buf;
r[3] = DIRBUFSIZ / MAXNAMLEN;
r[4] = d->dd_off2;
r[5] = DIRBUFSIZ;
r[6] = (int) "*";
if (e = os_swi (OS_GBPB, r))
{
__seterr (e);
free (d->dd_name);
free (d->dd_buf);
free (d);
return (-1);
}
for (i = r[3], s = d->dd_buf; i; i--)
while (*++s);
d->dd_loc = 0;
d->dd_size = s - d->dd_buf;
d->dd_off = (d->dd_off2 << DIRBUFSHIFT);
d->dd_off2 = r[4];
if (r[4] < 0 && !r[3])
return (-1);
return (0);
}
/* readdir() */
struct dirent *
readdir (d)
register DIR *d;
{
register struct dirent *r = NULL;
register int i;
register char *s;
if (!d)
return (0);
for (i = 0; i < MAXDIRS; i++)
{
if ((dirvals[i].__dirval) && (dirvals[i].which == d))
{
r = dirvals[i].__dirval;
break;
}
}
if (!r)
return (0);
while (d->dd_loc >= d->dd_size)
if (__nextdir (d))
return (0);
s = d->dd_buf + d->dd_loc;
i = strlen (s);
r->d_off = d->dd_off;
i++;
d->dd_off += i;
d->dd_loc += i;
if (i >= MAXNAMLEN)
s[i = MAXNAMLEN - 1] = 0;
memcpy (r->d_name, s, i);
r->d_namlen = i;
r->d_reclen = DIRSIZ (r);
/* The file serial number. This is the same as the st_ino member
that stat will return for the file. */
r->d_fileno = __get_file_serial_no (r->d_name);
return (r);
}
/* telldir() */
long
telldir (d)
DIR *d;
{
if (!d)
return (-1);
return (d->dd_off);
}
/* seekdir() */
void
seekdir (d, off)
DIR *d;
long off;
{
if (!d)
return;
if (d->dd_off2 != (off >> DIRBUFSHIFT))
{
d->dd_off2 = (((int) off) >> DIRBUFSHIFT);
d->dd_loc = 0;
d->dd_size = 0;
__nextdir (d);
}
d->dd_off = (size_t) off;
d->dd_loc = (size_t) off & (DIRBUFSHIFT - 1);
}
/* rewinddir() */
void (rewinddir) (d)
DIR *d;
{
rewinddir (d);
}
/* closedir() */
int
closedir (d)
DIR *d;
{
int i;
if (!d)
return (-1);
for (i = 0; i < MAXDIRS; i++)
{
if (dirvals[i].__dirval && (dirvals[i].which == d))
{
free (dirvals[i].__dirval);
dirvals[i].__dirval = 0;
dirvals[i].which = 0;
break;
}
}
free (d->dd_name);
free (d->dd_buf);
free (d);
return (0);
}